package com.t35.ssh.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.t35.ssh.dao.BaseDao;


public class BaseDaoImpl<T> implements BaseDao<T> {
	
	private HibernateTemplate hibernateTemplate;
	private Class<T> entityClass;
	
	@SuppressWarnings("unchecked")
	public BaseDaoImpl() {
		this.entityClass=(Class<T>) ((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}
	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}
	@Autowired
	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}

	@Override
	public Serializable save(T entity) {
		// TODO Auto-generated method stub
		return this.getHibernateTemplate().save(entity);
	}

	@Override
	public T get(Serializable id) {
		// TODO Auto-generated method stub
		return this.getHibernateTemplate().get(entityClass, id);
	}

	@Override
	public void update(T entity) {
		// TODO Auto-generated method stub
		this.getHibernateTemplate().update(entity);
	}

	@Override
	public void saveOrUpdate(T entity) {
		// TODO Auto-generated method stub
		this.getHibernateTemplate().saveOrUpdate(entity);
	}

	@Override
	public T merge(T entity) {
		// TODO Auto-generated method stub
		return this.getHibernateTemplate().merge(entity);
	}

	@Override
	public void delete(T entity) {
		// TODO Auto-generated method stub
		this.getHibernateTemplate().delete(entity);
	}

	@Override
	public void deleteAll(Collection<T> entities) {
		// TODO Auto-generated method stub
		this.getHibernateTemplate().deleteAll(entities);
	}




	@Override
	public Long getRowCount(final DetachedCriteria detachedCriteria) {
		// TODO Auto-generated method stub
		
		@SuppressWarnings({ "rawtypes", "unchecked" })
		Long row=this.getHibernateTemplate().execute(new HibernateCallback(){

			@Override
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				// TODO Auto-generated method stub
				Criteria criteria=detachedCriteria.getExecutableCriteria(session);
				criteria.setProjection(Projections.rowCount());
				Object result= criteria.uniqueResult();
				criteria.setProjection(null);
				return result;
			}
		});
		return row;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> findByExample(T exampleEntity) {
		// TODO Auto-generated method stub
		return this.getHibernateTemplate().findByExample(exampleEntity);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> find(String hql, Object... objects) {
		// TODO Auto-generated method stub
		return this.getHibernateTemplate().find(hql, objects);
	}
	@SuppressWarnings("unchecked")
	@Override
	public List<T> findAll() {
		// TODO Auto-generated method stub
		return this.getHibernateTemplate().findByCriteria(DetachedCriteria.forClass(this.entityClass));
	}
	@SuppressWarnings("unchecked")
	@Override
	public List<T> findByCriteria(DetachedCriteria criteria) {
		// TODO Auto-generated method stub
		return this.getHibernateTemplate().findByCriteria(criteria);
	}
	@SuppressWarnings("unchecked")
	@Override
	public List<T> findByCriteria(DetachedCriteria criteria, int firstResult, int maxResults) {
		// TODO Auto-generated method stub
		return this.getHibernateTemplate().findByCriteria(criteria, firstResult, maxResults);
	}
	@Override
	public List<T> findByPage(DetachedCriteria criteria, int pageNo, int pageSize) {
		// TODO Auto-generated method stub
		return this.findByCriteria(criteria, (pageNo-1)*pageSize, pageSize);
	}
	@SuppressWarnings("unchecked")
	@Override
	public List<Object[]> findProjectionsByCriteria(DetachedCriteria criteria) {
		// TODO Auto-generated method stub
		return this.getHibernateTemplate().findByCriteria(criteria);
	}


}
